/**
 * 
 */
package org.dicr.radius.dict;

/**
 * Attribute value types <br/>
 * TODO: <a href="https://tools.ietf.org/html/rfc6929#section-2.3">TLV Data Type</a><br/>
 * TODO: <a href="http://freeradius.org/radiusd/man/dictionary.html">vendor|(enctype=[1..3], has_tag)</a><br/>
 * 
 * @see <a href="http://tools.ietf.org/html/rfc2865#section-5">RFC 2865, section 5</a>
 */
public enum ValueType {
	/** 1-octet unsigned integer (by WiMAX) */
	BYTE("byte"),

	/** 2-octets unsigned integer (by WiMAX) */
	SHORT("short"),

	/** 4 octets unsigned integer */
	INTEGER("integer"),

	/** 4-octet signed integer (by WiMAX) */
	SIGNED("signed"),

	/** 8-octets value */
	INTEGER64("integer64", "ifid"),

	/** 1-253 octets containing UTF-8 encoded characters */
	STRING("string", "text"),

	/** 4-octets ip-address value */
	ADDRESS("address", "ipaddr"),

	/** 6 octets (1 reserved, 1 prefix, 4 ipaddr) */
	IPV4PREFIX("ipv4prefix"),

	/** 16 octets */
	IPV6ADDR("ipv6addr"),

	/** 18 octets (1 reserved, 1 prefix, 16 octets ipv6addr) */
	IPV6PREFIX("ipv6prefix"),

	/** 4/16 octets (if length 4, then "ipaddr", if length 16, then "ipv6addr") (by WiMAX) */
	COMBOIP("combo-ip"),

	/** 6 octets MAC-address (by FreeRadius) */
	ETHER("ether"),

	/** 32-bit value - seconds since 00:00:00 UTC, January 1, 1970 */
	DATE("date", "time"),

	/** type-length-value - encapsulated sub-attributes, i.e. Vendor-Specific -> WiMAX TLV -> WiMAX sub-tlv (by WiMAX) */
	TLV("tlv"),

	/** 1-253 raw octets containing binary data */
	OCTETS("octets", "abinary", "vsa");

	/** aliases of type name */
	private String[] aliases;

	/** Constructor */
	private ValueType(String... aliases) {
		this.aliases = aliases.length > 0 ? aliases : new String[] { this.toString().toLowerCase() };
	}

	/**
	 * Parse String and create type
	 * 
	 * @param name string name value
	 * @return type for name or null if type not found
	 */
	public static ValueType fromString(String name) {
		if (name == null) throw new IllegalArgumentException("null name");
		ValueType type = null;
		if (name.startsWith("octets[")) type = OCTETS;
		else {
			for (ValueType at : ValueType.values()) {
				for (String alias : at.aliases) {
					if (alias.equalsIgnoreCase(name)) {
						type = at;
						break;
					}
				}
			}
		}
		return type;
	}

	@Override
	public String toString() {
		return this.aliases[0].toLowerCase();
	}

}
